<html lang="en"><head></head><body>
    <form id="mainForm" method="post" action="https://run.stackblitz.com/api/angular/v1?file=src/app/app.component.ts" target="_self"><input type="hidden" name="files[src/app/app-routing.module.ts]" value="import { NgModule } from '@angular/core';
import { Routes, RouterModule }  from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  providers: [],
  exports: [RouterModule]
})
export class AppRoutingModule {}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.component.ts]" value="import { Component } from '@angular/core';

import { LoggerService }      from './logger.service';
import { UserContextService } from './user-context.service';
import { UserService }        from './user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {

  private userId = 1;

  constructor(logger: LoggerService, public userContext: UserContextService) {
    userContext.loadUser(this.userId);
    logger.logInfo('AppComponent initialized');
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.module.ts]" value="import { BrowserModule }                from '@angular/platform-browser';
import { FormsModule }                  from '@angular/forms';
import { HttpClientModule }             from '@angular/common/http';

// import { AppRoutingModule }             from './app-routing.module';
import { LocationStrategy,
         HashLocationStrategy }         from '@angular/common';
import { NgModule }                     from '@angular/core';

import { HeroData }                     from './hero-data';
import { InMemoryWebApiModule }         from 'angular-in-memory-web-api';


import { AppComponent }                 from './app.component';
import { HeroBioComponent }             from './hero-bio.component';
import { HeroBiosComponent,
         HeroBiosAndContactsComponent } from './hero-bios.component';
import { HeroOfTheMonthComponent }      from './hero-of-the-month.component';
import { HeroContactComponent }         from './hero-contact.component';
import { HeroesBaseComponent,
         SortedHeroesComponent }        from './sorted-heroes.component';
import { HighlightDirective }           from './highlight.directive';
import { ParentFinderComponent,
         AlexComponent,
         AliceComponent,
         CarolComponent,
         ChrisComponent,
         CraigComponent,
         CathyComponent,
         BarryComponent,
         BethComponent,
         BobComponent }                 from './parent-finder.component';
import { StorageComponent }             from './storage.component';

const declarations = [
    AppComponent,
    HeroBiosComponent, HeroBiosAndContactsComponent, HeroBioComponent,
    HeroesBaseComponent, SortedHeroesComponent,
    HeroOfTheMonthComponent, HeroContactComponent,
    HighlightDirective,
    ParentFinderComponent,
];

const a_components = [AliceComponent, AlexComponent ];

const b_components = [ BarryComponent, BethComponent, BobComponent ];

const c_components = [
  CarolComponent, ChrisComponent, CraigComponent,
  CathyComponent
];

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    InMemoryWebApiModule.forRoot(HeroData)
    // AppRoutingModule TODO: add routes
  ],
  declarations: [
    declarations,
    a_components,
    b_components,
    c_components,
    StorageComponent,
  ],
  bootstrap: [ AppComponent ],
  providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy }
  ]
})
export class AppModule { }


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/date-logger.service.ts]" value="/* tslint:disable:one-line*/
import { Injectable }    from '@angular/core';

import { LoggerService } from './logger.service';

@Injectable({
  providedIn: 'root'
})
export class DateLoggerService extends LoggerService
{
  logInfo(msg: any)  { super.logInfo(stamp(msg)); }
  logDebug(msg: any) { super.logInfo(stamp(msg)); }
  logError(msg: any) { super.logError(stamp(msg)); }
}

function stamp(msg: any) { return msg + ' at ' + new Date(); }


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-bio.component.ts]" value="import { Component, Input, OnInit } from '@angular/core';

import { HeroCacheService }         from './hero-cache.service';

@Component({
  selector: 'app-hero-bio',
  template: `
    <h4>{{hero.name}}</h4>
    <ng-content></ng-content>
    <textarea cols=&quot;25&quot; [(ngModel)]=&quot;hero.description&quot;></textarea>`,
  providers: [HeroCacheService]
})

export class HeroBioComponent implements OnInit  {
  @Input() heroId: number;

  constructor(private heroCache: HeroCacheService) { }

  ngOnInit() { this.heroCache.fetchCachedHero(this.heroId); }

  get hero() { return this.heroCache.hero; }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-bios.component.ts]" value="import { Component }             from '@angular/core';

import { HeroService }          from './hero.service';
import { LoggerService }        from './logger.service';

//////// HeroBiosComponent ////
@Component({
  selector: 'app-hero-bios',
  template: `
    <app-hero-bio [heroId]=&quot;1&quot;></app-hero-bio>
    <app-hero-bio [heroId]=&quot;2&quot;></app-hero-bio>
    <app-hero-bio [heroId]=&quot;3&quot;></app-hero-bio>`,
  providers: [HeroService]
})
export class HeroBiosComponent {
  constructor(logger: LoggerService) {
    logger.logInfo('Creating HeroBiosComponent');
  }
}

//////// HeroBiosAndContactsComponent ////
@Component({
  selector: 'app-hero-bios-and-contacts',
  template: `
    <app-hero-bio [heroId]=&quot;1&quot;> <app-hero-contact></app-hero-contact> </app-hero-bio>
    <app-hero-bio [heroId]=&quot;2&quot;> <app-hero-contact></app-hero-contact> </app-hero-bio>
    <app-hero-bio [heroId]=&quot;3&quot;> <app-hero-contact></app-hero-contact> </app-hero-bio>`,
  providers: [HeroService]
})
export class HeroBiosAndContactsComponent {
  constructor(logger: LoggerService) {
    logger.logInfo('Creating HeroBiosAndContactsComponent');
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-cache.service.ts]" value="import { Injectable }  from '@angular/core';

import { Hero }        from './hero';
import { HeroService } from './hero.service';

@Injectable()
export class HeroCacheService {
  hero: Hero;
  constructor(private heroService: HeroService) {}

  fetchCachedHero(id: number) {
    if (!this.hero) {
      this.hero = this.heroService.getHeroById(id);
    }
    return this.hero;
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-contact.component.ts]" value="import { Component, Host, Optional } from '@angular/core';

import { HeroCacheService } from './hero-cache.service';
import { LoggerService }    from './logger.service';

@Component({
  selector: 'app-hero-contact',
  template: `
  <div>Phone #: {{phoneNumber}}
  <span *ngIf=&quot;hasLogger&quot;>!!!</span></div>`
})
export class HeroContactComponent {

  hasLogger = false;

  constructor(
      @Host() // limit to the host component's instance of the HeroCacheService
      private heroCache: HeroCacheService,

      @Host()     // limit search for logger; hides the application-wide logger
      @Optional() // ok if the logger doesn't exist
      private loggerService: LoggerService
  ) {
    if (loggerService) {
      this.hasLogger = true;
      loggerService.logInfo('HeroContactComponent can log!');
    }
  }

  get phoneNumber() { return this.heroCache.hero.phone; }

}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-data.ts]" value="import { Hero } from './hero';

export class HeroData {
  createDb() {
    let heroes = [
      new Hero(1, 'Windstorm'),
      new Hero(2, 'Bombasto'),
      new Hero(3, 'Magneta'),
      new Hero(4, 'Tornado')
    ];
    return {heroes};
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero-of-the-month.component.ts]" value="/* tslint:disable:one-line*/
import { InjectionToken } from '@angular/core';

export const TITLE = new InjectionToken<string>('title');

import { Component, Inject } from '@angular/core';

import { DateLoggerService } from './date-logger.service';
import { Hero }              from './hero';
import { HeroService }       from './hero.service';
import { LoggerService }     from './logger.service';
import { MinimalLogger }     from './minimal-logger.service';
import { RUNNERS_UP,
         runnersUpFactory }  from './runners-up';

const someHero = new Hero(42, 'Magma', 'Had a great month!', '555-555-5555');

@Component({
  selector: 'app-hero-of-the-month',
  templateUrl: './hero-of-the-month.component.html',
  providers: [
    { provide: Hero,          useValue:    someHero },
    { provide: TITLE,         useValue:   'Hero of the Month' },
    { provide: HeroService,   useClass:    HeroService },
    { provide: LoggerService, useClass:    DateLoggerService },
    { provide: MinimalLogger, useExisting: LoggerService },
    { provide: RUNNERS_UP,    useFactory:  runnersUpFactory(2), deps: [Hero, HeroService] }
  ]
})
export class HeroOfTheMonthComponent {
  logs: string[] = [];

  constructor(
      logger: MinimalLogger,
      public heroOfTheMonth: Hero,
      @Inject(RUNNERS_UP) public runnersUp: string,
      @Inject(TITLE) public title: string)
  {
    this.logs = logger.logs;
    logger.logInfo('starting up');
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero.service.ts]" value="import { Injectable } from '@angular/core';
import { Hero }       from './hero';

@Injectable({
  providedIn: 'root'
})
export class HeroService {

  // TODO: move to database
  private heroes: Array<Hero> = [
    new Hero(1, 'RubberMan', 'Hero of many talents', '123-456-7899'),
    new Hero(2, 'Magma', 'Hero of all trades', '555-555-5555'),
    new Hero(3, 'Dr Nice', 'The name says it all', '111-222-3333')
 ];

  getHeroById(id: number): Hero {
    return this.heroes.find(hero => hero.id === id);
  }

  getAllHeroes(): Array<Hero> {
    return this.heroes;
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/hero.ts]" value="export class Hero {
  constructor(
    public id: number,
    public name: string,
    public description?: string,
    public phone?: string) {
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/highlight.directive.ts]" value="import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  @Input('appHighlight') highlightColor: string;

  private el: HTMLElement;

  constructor(el: ElementRef) {
    this.el = el.nativeElement;
  }

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || 'cyan');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.style.backgroundColor = color;
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/logger.service.ts]" value="import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LoggerService {
  logs: string[] = [];

  logInfo(msg: any)  { this.log(`INFO: ${msg}`); }
  logDebug(msg: any) { this.log(`DEBUG: ${msg}`); }
  logError(msg: any) { this.log(`ERROR: ${msg}`, true); }

  private log(msg: any, isErr = false) {
    this.logs.push(msg);
    isErr ? console.error(msg) : console.log(msg);
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/minimal-logger.service.ts]" value="// Class used as a &quot;narrowing&quot; interface that exposes a minimal logger
// Other members of the actual implementation are invisible
export abstract class MinimalLogger {
  logs: string[];
  logInfo: (msg: string) => void;
}

/*
// Transpiles to:
  var MinimalLogger = (function () {
    function MinimalLogger() {}
    return MinimalLogger;
  }());
  exports(&quot;MinimalLogger&quot;, MinimalLogger);
*/

// See http://stackoverflow.com/questions/43154832/unexpected-token-export-in-angular-app-with-systemjs-and-typescript/
export const _ = 0;


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/parent-finder.component.ts]" value="/* tslint:disable:no-unused-variable component-selector-name one-line check-open-brace */
/* tslint:disable:*/
import { Component, forwardRef, Optional, SkipSelf } from '@angular/core';

// A component base class (see AlexComponent)
export abstract class Base { name = 'Count Basie'; }

// Marker class, used as an interface
export abstract class Parent { name: string; }

const DifferentParent = Parent;

// Helper method to provide the current component instance in the name of a `parentType`.
// The `parentType` defaults to `Parent` when omitting the second parameter.
export function provideParent
  (component: any, parentType?: any) {
    return { provide: parentType || Parent, useExisting: forwardRef(() => component) };
  }

// Simpler syntax version that always provides the component in the name of `Parent`.
export function provideTheParent
  (component: any) {
    return { provide: Parent, useExisting: forwardRef(() => component) };
  }


///////// C - Child //////////
const templateC = `
  <div class=&quot;c&quot;>
    <h3>{{name}}</h3>
    <p>My parent is {{parent?.name}}</p>
  </div>`;

@Component({
  selector: 'carol',
  template: templateC
})
export class CarolComponent {
  name = 'Carol';
  constructor( @Optional() public parent: Parent ) { }
}

@Component({
  selector: 'chris',
  template: templateC
})
export class ChrisComponent {
  name = 'Chris';
  constructor( @Optional() public parent: Parent ) { }
}

//////  Craig ///////////
/**
 * Show we cannot inject a parent by its base class.
 */
@Component({
  selector: 'craig',
  template: `
  <div class=&quot;c&quot;>
    <h3>Craig</h3>
    {{alex ? 'Found' : 'Did not find'}} Alex via the base class.
  </div>`
})
export class CraigComponent {
  constructor( @Optional() public alex: Base ) { }
}

//////// B - Parent /////////
const templateB = `
  <div class=&quot;b&quot;>
    <div>
      <h3>{{name}}</h3>
      <p>My parent is {{parent?.name}}</p>
    </div>
    <carol></carol>
    <chris></chris>
  </div>`;

@Component({
  selector:   'barry',
  template:   templateB,
  providers:  [{ provide: Parent, useExisting: forwardRef(() => BarryComponent) }]
})
export class BarryComponent implements Parent {
  name = 'Barry';
  constructor( @SkipSelf() @Optional() public parent: Parent ) { }
}

@Component({
  selector:   'bob',
  template:   templateB,
  providers:  [ provideParent(BobComponent) ]
})
export class BobComponent implements Parent {
  name = 'Bob';
  constructor( @SkipSelf() @Optional() public parent: Parent ) { }
}

@Component({
  selector:   'beth',
  template:   templateB,
  providers:  [ provideParent(BethComponent, DifferentParent) ]
})
export class BethComponent implements Parent {
  name = 'Beth';
  constructor( @SkipSelf() @Optional() public parent: Parent ) { }
}

///////// A - Grandparent //////

@Component({
  selector: 'alex',
  template: `
    <div class=&quot;a&quot;>
      <h3>{{name}}</h3>
      <cathy></cathy>
      <craig></craig>
      <carol></carol>
    </div>`,
  providers: [{ provide: Parent, useExisting: forwardRef(() => AlexComponent) }],
})
// TODO: Add `... implements Parent` to class signature
export class AlexComponent extends Base
{
  name = 'Alex';
}

/////

@Component({
  selector: 'alice',
  template: `
    <div class=&quot;a&quot;>
      <h3>{{name}}</h3>
      <barry></barry>
      <beth></beth>
      <bob></bob>
      <carol></carol>
    </div> `,
  providers:  [ provideParent(AliceComponent) ]
})
export class AliceComponent implements Parent
{
  name = 'Alice';
}

//////  Cathy ///////////
/**
 * Show we can inject a parent by component type
 */
@Component({
  selector: 'cathy',
  template: `
  <div class=&quot;c&quot;>
    <h3>Cathy</h3>
    {{alex ? 'Found' : 'Did not find'}} Alex via the component class.<br>
  </div>`
})
export class CathyComponent {
  constructor( @Optional() public alex: AlexComponent ) { }
}

///////// ParentFinder //////
@Component({
  selector: 'app-parent-finder',
  template: `
    <h2>Parent Finder</h2>
    <alex></alex>
    <alice></alice>`
})
export class ParentFinderComponent { }


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/runners-up.ts]" value="import { InjectionToken } from '@angular/core';

import { Hero }        from './hero';
import { HeroService } from './hero.service';

export const RUNNERS_UP = new InjectionToken<string>('RunnersUp');

export function runnersUpFactory(take: number) {
  return (winner: Hero, heroService: HeroService): string => {
    /* ... */
    return heroService
          .getAllHeroes()
          .filter((hero) => hero.name !== winner.name)
          .map(hero => hero.name)
          .slice(0, Math.max(0, take))
          .join(', ');
  };
};


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/sorted-heroes.component.ts]" value="import { Component, OnInit } from '@angular/core';

import { Hero }              from './hero';
import { HeroService }       from './hero.service';

/////// HeroesBaseComponent /////
@Component({
  selector: 'app-unsorted-heroes',
  template: `<div *ngFor=&quot;let hero of heroes&quot;>{{hero.name}}</div>`,
  providers: [HeroService]
})
export class HeroesBaseComponent implements OnInit {
  constructor(private heroService: HeroService) { }

  heroes: Array<Hero>;

  ngOnInit() {
    this.heroes = this.heroService.getAllHeroes();
    this.afterGetHeroes();
  }

  // Post-process heroes in derived class override.
  protected afterGetHeroes() {}

}

/////// SortedHeroesComponent /////
@Component({
  selector: 'app-sorted-heroes',
  template: `<div *ngFor=&quot;let hero of heroes&quot;>{{hero.name}}</div>`,
  providers: [HeroService]
})
export class SortedHeroesComponent extends HeroesBaseComponent {
  constructor(heroService: HeroService) {
    super(heroService);
  }

  protected afterGetHeroes() {
    this.heroes = this.heroes.sort((h1, h2) => {
      return h1.name < h2.name ? -1 :
            (h1.name > h2.name ? 1 : 0);
    });
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/storage.component.ts]" value="import { Component, OnInit, Self, SkipSelf } from '@angular/core';
import { BROWSER_STORAGE, BrowserStorageService } from './storage.service';

@Component({
  selector: 'app-storage',
  template: `
    Open the inspector to see the local/session storage keys:

    <h3>Session Storage</h3>
    <button (click)=&quot;setSession()&quot;>Set Session Storage</button>

    <h3>Local Storage</h3>
    <button (click)=&quot;setLocal()&quot;>Set Local Storage</button>
  `,
  providers: [
    BrowserStorageService,
    { provide: BROWSER_STORAGE, useFactory: () => sessionStorage }
  ]
})
export class StorageComponent implements OnInit {

  constructor(
    @Self() private sessionStorageService: BrowserStorageService,
    @SkipSelf() private localStorageService: BrowserStorageService,
  ) { }

  ngOnInit() {
  }

  setSession() {
    this.sessionStorageService.set('hero', 'Dr Nice - Session');
  }

  setLocal() {
    this.localStorageService.set('hero', 'Dr Nice - Local');
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/storage.service.ts]" value="import { Inject, Injectable, InjectionToken } from '@angular/core';

export const BROWSER_STORAGE = new InjectionToken<Storage>('Browser Storage', {
  providedIn: 'root',
  factory: () => localStorage
});

@Injectable({
  providedIn: 'root'
})
export class BrowserStorageService {
  constructor(@Inject(BROWSER_STORAGE) public storage: Storage) {}

  get(key: string) {
    this.storage.getItem(key);
  }

  set(key: string, value: string) {
    this.storage.setItem(key, value);
  }

  remove(key: string) {
    this.storage.removeItem(key);
  }

  clear() {
    this.storage.clear();
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/user-context.service.ts]" value="import { Injectable }    from '@angular/core';

import { LoggerService } from './logger.service';
import { UserService }   from './user.service';

@Injectable({
  providedIn: 'root'
})
export class UserContextService {
  name: string;
  role: string;
  loggedInSince: Date;

  constructor(private userService: UserService, private loggerService: LoggerService) {
    this.loggedInSince = new Date();
  }

  loadUser(userId: number) {
    let user = this.userService.getUserById(userId);
    this.name = user.name;
    this.role = user.role;

    this.loggerService.logDebug('loaded User');
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/user.service.ts]" value="import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  getUserById(userId: number): any {
    return {name: 'Bombasto', role: 'Admin'};
  }
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/environments/environment.prod.ts]" value="export const environment = {
  production: true
};


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/environments/environment.ts]" value="// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

export const environment = {
  production: false
};

/*
 * For easier debugging in development mode, you can import the following file
 * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
 *
 * This import should be commented out in production mode because it will have a negative impact
 * on performance if an error is thrown.
 */
// import 'zone.js/dist/zone-error';  // Included with Angular CLI.


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/main.ts]" value="import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/polyfills.ts]" value="/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called &quot;evergreen&quot; browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/guide/browser-support
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js';  // Run `npm install --save classlist.js`.

/**
 * Web Animations `@angular/platform-browser/animations`
 * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
 * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
 */
// import 'web-animations-js';  // Run `npm install --save web-animations-js`.

/**
 * By default, zone.js will patch all possible macroTask and DomEvents
 * user can disable parts of macroTask/DomEvents patch by setting following flags
 * because those flags need to be set before `zone.js` being loaded, and webpack
 * will put import in the top of bundle, so user need to create a separate file
 * in this directory (for example: zone-flags.ts), and put the following flags
 * into that file, and then add the following code before importing zone.js.
 * import './zone-flags.ts';
 *
 * The flags allowed in zone-flags.ts are listed here.
 *
 * The following flags will work for all browsers.
 *
 * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch
 * requestAnimationFrame
 * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
 * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch
 * specified eventNames
 *
 *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
 *  with the following flag, it will bypass `zone.js` patch for IE/Edge
 *
 *  (window as any).__Zone_enable_cross_context_check = true;
 *
 */

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import 'zone.js/dist/zone'; // Included with Angular CLI.

/***************************************************************************************************
 * APPLICATION IMPORTS
 */


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/assets/sample.css]" value=".di-component{
  padding: 10px;
  width:300px;
  margin-bottom: 10px;
}
div[myHighlight] {
  padding: 2px 8px;
}

/* Parent Finder */
.a, .b, .c {
  margin: 6px 2px 6px;
  padding: 4px 6px;
}
.a {
  border: solid 2px black;
}
.b {
  background: lightblue;
  border: solid 1px darkblue;
  display: flex;
}
.c {
  background: pink;
  border: solid 1px red;
}

/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/styles.css]" value="/* Global Styles */
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body {
  margin: 2em;
}
body, input[text], button {
  color: #333;
  font-family: Cambria, Georgia;
}
a {
  cursor: pointer;
  cursor: hand;
}
button {
  font-family: Arial;
  background-color: #eee;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
  cursor: hand;
}
button:hover {
  background-color: #cfd8dc;
}
button:disabled {
  background-color: #eee;
  color: #aaa;
  cursor: auto;
}

/* Navigation link styles */
nav a {
  padding: 5px 10px;
  text-decoration: none;
  margin-right: 10px;
  margin-top: 10px;
  display: inline-block;
  background-color: #eee;
  border-radius: 4px;
}
nav a:visited, a:link {
  color: #607D8B;
}
nav a:hover {
  color: #039be5;
  background-color: #CFD8DC;
}
nav a.active {
  color: #039be5;
}

/* everywhere else */
* {
  font-family: Arial, Helvetica, sans-serif;
}


/*
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/"><input type="hidden" name="files[src/app/app.component.html]" value="<h1>DI Cookbook</h1>
<div class=&quot;di-component&quot;>
  <h3>Logged in user</h3>
  <div>Name: {{userContext.name}}</div>
  <div>Role: {{userContext.role}}</div>
</div>

<div class=&quot;di-component&quot;>
  <h3>Hero Bios</h3>
  <app-hero-bios></app-hero-bios>
</div>

<div id=&quot;highlight&quot;  class=&quot;di-component&quot;  appHighlight>
  <h3>Hero Bios and Contacts</h3>
  <div appHighlight=&quot;yellow&quot;>
    <app-hero-bios-and-contacts></app-hero-bios-and-contacts>
  </div>
</div>

<div class=&quot;di-component&quot;>
  <app-hero-of-the-month></app-hero-of-the-month>
</div>

<div class=&quot;di-component&quot;>
  <h3>Unsorted Heroes</h3>
  <app-unsorted-heroes></app-unsorted-heroes>
</div>

<div class=&quot;di-component&quot;>
  <h3>Sorted Heroes</h3>
  <app-sorted-heroes></app-sorted-heroes>
</div>

<div class=&quot;di-component&quot;>
  <app-parent-finder></app-parent-finder>
</div>

<div class=&quot;di-component&quot;>
  <app-storage></app-storage>
</div>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/app/hero-of-the-month.component.html]" value="<h3>{{title}}</h3>
<div>Winner: <strong>{{heroOfTheMonth.name}}</strong></div>
<div>Reason for award: <strong>{{heroOfTheMonth.description}}</strong></div>
<div>Runners-up: <strong id=&quot;rups1&quot;>{{runnersUp}}</strong></div>

<p>Logs:</p>
<div id=&quot;logs&quot;>
  <div *ngFor=&quot;let log of logs&quot;>{{log}}</div>
</div>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[src/index.html]" value="<!DOCTYPE html>
<html lang=&quot;en&quot;>
  <head>
    <base href=&quot;/&quot;>
    <meta charset=&quot;UTF-8&quot;>
    <title>Dependency Injection</title>
    <meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;>
    <link rel=&quot;stylesheet&quot; href=&quot;assets/sample.css&quot;>
  </head>

  <body>
    <app-root></app-root>
  </body>

</html>


<!-- 
Copyright Google LLC. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->"><input type="hidden" name="files[angular.json]" value="{
  &quot;$schema&quot;: &quot;./node_modules/@angular/cli/lib/config/schema.json&quot;,
  &quot;version&quot;: 1,
  &quot;newProjectRoot&quot;: &quot;projects&quot;,
  &quot;projects&quot;: {
    &quot;angular.io-example&quot;: {
      &quot;projectType&quot;: &quot;application&quot;,
      &quot;schematics&quot;: {},
      &quot;root&quot;: &quot;&quot;,
      &quot;sourceRoot&quot;: &quot;src&quot;,
      &quot;prefix&quot;: &quot;app&quot;,
      &quot;architect&quot;: {
        &quot;build&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:browser&quot;,
          &quot;options&quot;: {
            &quot;outputPath&quot;: &quot;dist&quot;,
            &quot;index&quot;: &quot;src/index.html&quot;,
            &quot;main&quot;: &quot;src/main.ts&quot;,
            &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
            &quot;tsConfig&quot;: &quot;tsconfig.app.json&quot;,
            &quot;assets&quot;: [
              &quot;src/favicon.ico&quot;,
              &quot;src/assets&quot;
            ],
            &quot;styles&quot;: [
              &quot;src/styles.css&quot;
            ],
            &quot;scripts&quot;: []
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;fileReplacements&quot;: [
                {
                  &quot;replace&quot;: &quot;src/environments/environment.ts&quot;,
                  &quot;with&quot;: &quot;src/environments/environment.prod.ts&quot;
                }
              ],
              &quot;optimization&quot;: true,
              &quot;outputHashing&quot;: &quot;all&quot;,
              &quot;sourceMap&quot;: false,
              &quot;extractCss&quot;: true,
              &quot;namedChunks&quot;: false,
              &quot;aot&quot;: true,
              &quot;extractLicenses&quot;: true,
              &quot;vendorChunk&quot;: false,
              &quot;buildOptimizer&quot;: true,
              &quot;budgets&quot;: [
                {
                  &quot;type&quot;: &quot;initial&quot;,
                  &quot;maximumWarning&quot;: &quot;2mb&quot;,
                  &quot;maximumError&quot;: &quot;5mb&quot;
                }
              ]
            }
          }
        },
        &quot;serve&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:dev-server&quot;,
          &quot;options&quot;: {
            &quot;browserTarget&quot;: &quot;angular.io-example:build&quot;
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;browserTarget&quot;: &quot;angular.io-example:build:production&quot;
            }
          }
        },
        &quot;extract-i18n&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:extract-i18n&quot;,
          &quot;options&quot;: {
            &quot;browserTarget&quot;: &quot;angular.io-example:build&quot;
          }
        },
        &quot;test&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:karma&quot;,
          &quot;options&quot;: {
            &quot;main&quot;: &quot;src/test.ts&quot;,
            &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
            &quot;tsConfig&quot;: &quot;tsconfig.spec.json&quot;,
            &quot;karmaConfig&quot;: &quot;karma.conf.js&quot;,
            &quot;assets&quot;: [
              &quot;src/favicon.ico&quot;,
              &quot;src/assets&quot;
            ],
            &quot;styles&quot;: [
              &quot;src/styles.css&quot;
            ],
            &quot;scripts&quot;: []
          }
        },
        &quot;lint&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:tslint&quot;,
          &quot;options&quot;: {
            &quot;tsConfig&quot;: [
              &quot;tsconfig.app.json&quot;,
              &quot;tsconfig.spec.json&quot;,
              &quot;e2e/tsconfig.json&quot;
            ],
            &quot;exclude&quot;: [
              &quot;**/node_modules/**&quot;
            ]
          }
        },
        &quot;e2e&quot;: {
          &quot;builder&quot;: &quot;@angular-devkit/build-angular:protractor&quot;,
          &quot;options&quot;: {
            &quot;protractorConfig&quot;: &quot;e2e/protractor.conf.js&quot;,
            &quot;devServerTarget&quot;: &quot;angular.io-example:serve&quot;
          },
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;devServerTarget&quot;: &quot;angular.io-example:serve:production&quot;
            }
          }
        }
      }
    }
  },
  &quot;defaultProject&quot;: &quot;angular.io-example&quot;
}
"><input type="hidden" name="tags[0]" value="angular"><input type="hidden" name="tags[1]" value="example"><input type="hidden" name="tags[2]" value="cookbook"><input type="hidden" name="description" value="Angular Example - Dependency Injection"><input type="hidden" name="dependencies" value="{&quot;@angular/animations&quot;:&quot;^8.0.0&quot;,&quot;@angular/common&quot;:&quot;^8.0.0&quot;,&quot;@angular/compiler&quot;:&quot;^8.0.0&quot;,&quot;@angular/core&quot;:&quot;^8.0.0&quot;,&quot;@angular/forms&quot;:&quot;^8.0.0&quot;,&quot;@angular/platform-browser&quot;:&quot;^8.0.0&quot;,&quot;@angular/platform-browser-dynamic&quot;:&quot;^8.0.0&quot;,&quot;@angular/router&quot;:&quot;^8.0.0&quot;,&quot;angular-in-memory-web-api&quot;:&quot;^0.8.0&quot;,&quot;core-js&quot;:&quot;^2.5.4&quot;,&quot;rxjs&quot;:&quot;^6.5.1&quot;,&quot;tslib&quot;:&quot;^1.10.0&quot;,&quot;web-animations-js&quot;:&quot;^2.3.1&quot;,&quot;zone.js&quot;:&quot;~0.10.2&quot;,&quot;jasmine-core&quot;:&quot;~2.99.1&quot;,&quot;jasmine-marbles&quot;:&quot;^0.6.0&quot;}"></form>
    <script>
      var embedded = 'ctl=1';
      var isEmbedded = window.location.search.indexOf(embedded) > -1;

      if (isEmbedded) {
        var form = document.getElementById('mainForm');
        var action = form.action;
        var actionHasParams = action.indexOf('?') > -1;
        var symbol = actionHasParams ? '&' : '?'
        form.action = form.action + symbol + embedded;
      }
      document.getElementById("mainForm").submit();
    </script>
    </body></html>